package jmine.tec.aom.domain.impl;

import java.util.HashSet;
import java.util.Set;

import jmine.tec.aom.domain.AbstractPropertyValue;
import jmine.tec.aom.domain.Propertized;
import jmine.tec.aom.domain.Property;
import jmine.tec.aom.util.BasePropertyHandler;

/**
 * Simple implementation of {@link Propertized}
 * 
 * @author jrenaut
 */
public abstract class AbstractPropertized implements Propertized {

    private Propertized propertyHandler;

    private Propertized parent;

    /**
     * C'tor
     */
    public AbstractPropertized() {
    }

    /**
     * C'tor
     * 
     * @param parent parent.
     */
    public AbstractPropertized(Propertized parent) {
        this.parent = parent;
    }

    /**
     * @return propertyHandler
     */
    protected Propertized getPropertyHandler() {
        if (this.propertyHandler == null) {
            this.propertyHandler = this.doGetPropertyHandler();
        }
        return this.propertyHandler;
    }

    /**
     * @return the Propertized that will handle {@link Property} and {@link AbstractPropertyValue} for this {@link Propertized}.
     */
    protected Propertized doGetPropertyHandler() {
        return new BasePropertyHandler(this.parent, new HashSet<AbstractPropertyValue<?>>());
    }

    /**
     * {@inheritDoc}
     */
    public Set<Property> getProperties() {
        return this.getPropertyHandler().getProperties();
    }

    /**
     * {@inheritDoc}
     */
    public Set<Property> getRealProperties() {
        return this.getPropertyHandler().getRealProperties();
    }

    /**
     * {@inheritDoc}
     */
    public Set<Property> getSyntheticProperties() {
        return this.getPropertyHandler().getSyntheticProperties();
    }

    /**
     * {@inheritDoc}
     */
    public Set<AbstractPropertyValue<?>> getPropertyValues() {
        return this.getPropertyHandler().getPropertyValues();
    }

    /**
     * {@inheritDoc}
     */
    public Propertized getParent() {
        return this.getPropertyHandler().getParent();
    }

    /**
     * {@inheritDoc}
     */
    public Property getPropertyByName(String name) {
        return this.getPropertyHandler().getPropertyByName(name);
    }

    /**
     * {@inheritDoc}
     */
    public Property getPropertyByMnemonic(String mnemonic) {
        return this.getPropertyHandler().getPropertyByMnemonic(mnemonic);
    }

    /**
     * {@inheritDoc}
     */
    public AbstractPropertyValue getPropertyValue(Property property) {
        return this.getPropertyHandler().getPropertyValue(property);
    }

    /**
     * {@inheritDoc}
     */
    public void removePropertyValue(AbstractPropertyValue propertyValue) {
        this.getPropertyHandler().removePropertyValue(propertyValue);
    }

    /**
     * {@inheritDoc}
     */
    public void addPropertyValue(AbstractPropertyValue propertyValue) {
        this.getPropertyHandler().addPropertyValue(propertyValue);
    }

}
